import { TsconfigAliases } from "@/aliases.ts"
import { PackageExternalOptionsBase } from "@/externals.ts"
import { removePathExtension } from "@/utils.ts"
import { globSync } from "node:fs"
import { relative, resolve } from "node:path"

/**
 * 是否以及如何在构建前清理输出目录。
 *
 * 1. `true`: （默认）：当在 `root` 内时清理输出目录，如果在外部则警告。
 * 2. `false`: 不清理输出目录。
 * 3. `"force"`: 无论是否在 `root` 内都清理输出目录。
 */
export type CleanOutdirOptions = boolean | "force"

export type SpecialBuildOption = {
  mode: "lib" | "bin"
  input: string // Not glob.
  outdir: string
  cleanOutdir?: CleanOutdirOptions
}

export type BuildOptions = {
  root?: string
  src?: string
  out?: string
  bin?: string | string[] // Glob.
  lib?: string | string[] // Glob.
  specials?: Record<string, SpecialBuildOption>
  cleanOutdir?: CleanOutdirOptions

  tsconfig?: string | TsconfigAliases
  external?: PackageExternalOptionsBase
}

/**
 * 获取适配于 Rolldown 入口键值对配置格式的 {@link Record} 配置。
 *
 * 1. 根据相对于 {@link src} 的相对路径，基于 {@link pattern} 生成。
 * 2. 输出的键值对中其键为相对于 {@link src} 的相对路径基础上去除后缀。
 * 3. 通常用以确保最后输出的文件具有相同的相对路径结构。
 *
 * @param src 源代码根目录的路径，用于确定其键和值的相对路径。
 * @param pattern 模式匹配字符串或列表。
 * @returns 复合 Rolldown 入口键值对配置格式的 {@link Record}。
 */
export function resolveEntries(src: string, pattern?: string | string[]) {
  const handler: Record<string, string> = {}
  for (const path of globSync(pattern || [])) {
    const name = removePathExtension(relative(resolve(src), resolve(path)))
    handler[name] = path
  }
  return handler
}
